首页 > 试题广场 >

购物单

[编程题]购物单
  • 热度指数:422439 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
主件 附件
电脑 打印机,扫描仪
书柜 图书
书桌 台灯,文具
工作椅
如果要买归类为附件的物品,必须先买该附件所属的主件,且每件物品只能购买一次。
每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。
王强查到了每件物品的价格(都是 10 元的整数倍),而他只有 N 元的预算。除此之外,他给每件物品规定了一个重要度,用整数 1 ~ 5 表示。他希望在花费不超过 N 元的前提下,使自己的满意度达到最大。
满意度是指所购买的每件物品的价格与重要度的乘积的总和,假设设第i件物品的价格为,重要度为,共选中了k件物品,编号依次为j_1,j_2,...,j_k,则满意度为:。(其中 * 为乘号)
请你帮助王强计算可获得的最大的满意度。




输入描述:

输入的第 1 行,为两个正整数N,m,用一个空格隔开:

(其中 N ( N<32000 )表示总钱数, m (m <60 )为可购买的物品的个数。)


从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数 v p q


(其中 v 表示该物品的价格( v<10000 ), p 表示该物品的重要度( 1 5 ), q 表示该物品是主件还是附件。如果 q=0 ,表示该物品为主件,如果 q>0 ,表示该物品为附件, q 是所属主件的编号)

 




输出描述:
 输出一个正整数,为张强可以获得的最大的满意度。
示例1

输入

1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0

输出

2200
示例2

输入

50 5
20 3 5
20 3 5
10 3 0
10 2 0
10 1 0

输出

130

说明

由第1行可知总钱数N为50以及希望购买的物品个数m为5;
第2和第3行的q为5,说明它们都是编号为5的物品的附件;
第4~6行的q都为0,说明它们都是主件,它们的编号依次为3~5;
所以物品的价格与重要度乘积的总和的最大值为10*1+20*3+20*3=130       
let lineArr = readline().split(" ");
let total = +lineArr[0],
  num = +lineArr[1];

function solution(total, num) {
  const subject = {},
    dep = {};
  for (let i = 1; i <= num; i++) {
    const [v, p, q] = readline().split(" ").map(Number);
    if (q == 0) {
      subject[i] = [v, p];
    } else {
      if (q in dep) {
        dep[q].push([v, p]);
      } else {
        dep[q] = [[v, p]];
      }
    }
  }
  // price[i][j]表示第i件主体第j种组合时的价格
  // stasifaction[i][j]表示第i件主体第j种组合时的满意度
  const price = [],
    stasifaction = [];
  for (let v in subject) {
    // 只有主体时
    const _p = [subject[v][0]];
    const _s = [subject[v][0] * subject[v][1]];
    const _dep = dep[v];
    if (_dep) {
      _p.push(_p[0] + _dep[0][0]);
      _s.push(_s[0] + _dep[0][0] * _dep[0][1]);
      if (_dep.length > 1) {
        _p.push(_p[0] + _dep[1][0]);
        _s.push(_s[0] + _dep[1][0] * _dep[1][1]);
        _p.push(_p[1] + _p[2] - _p[0]);
        _s.push(_s[1] + _s[2] - _s[0]);
      }
    }
    price.push(_p);
    stasifaction.push(_s);
  }
  const dp = new Array(total + 1).fill(0);
  for (let i = 0; i < price.length; i++) {
    for (let j = total; j >= 0; j -= 10) {
      for (let k = 0; k < price[i].length; k++) {
        if (price[i][k] <= j) {
          // 比的是满意度
          dp[j] = Math.max(dp[j], dp[j - price[i][k]] + stasifaction[i][k]);
        }
      }
    }
  }
  console.log(dp[total]);
}
solution(total, num);

发表于 2022-08-05 02:02:57 回复(0)
let line1 = readline()
const n = parseInt(line1.split(' ')[0]), m = parseInt(line1.split(' ')[1])
const v = [''], w = [''], s = ['']
let index = 0
while(index < m) {
    let line = readline().split(' ')
    v.push(parseInt(line[0]))
    w.push(parseInt(line[1]))
    s.push(parseInt(line[2]))
    index++
}



const solve = (n, m, v, w, s) => {
    const dp = new Array(m+1).fill(0).map(() => new Array(n+1).fill(0))
    let res = 0
    for(let i=1;i<=m;i++) {
        for(let j=0;j<=n;j++) {
            if (!s[i]) {
                if(j >= v[i]){ // 主件
                    const sub = [] // 收集所有附件
                    for (let k=1;k<=s.length;k++) {
                        if (s[k] == i) sub.push(k)
                    }
                    // 0附件
                    dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j - v[i]] + w[i]*v[i])
                    if(sub[0] && j>= v[i]+v[sub[0]]) {
                        dp[i][j] = Math.max(dp[i][j], dp[i-1][j - v[i] - v[sub[0]]] + w[i]*v[i] + w[sub[0]] * v[sub[0]])
                    }
                    if(sub[1] && j>= v[i]+v[sub[1]]) {
                        dp[i][j] = Math.max(dp[i][j], dp[i-1][j - v[i] - v[sub[1]]] + w[i]*v[i] + w[sub[1]] * v[sub[1]])
                    }
                    if (sub.length == 2 && j>= v[i]+v[sub[1]]+v[sub[0]]) {
                        dp[i][j] = Math.max(dp[i][j], dp[i-1][j-v[i]-v[sub[0]]-v[sub[1]]] +w[i]*v[i]+w[sub[1]] * v[sub[1]]+w[sub[0]] * v[sub[0]])
                    }
                    res = Math.max(res, dp[i][j])
                } else dp[i][j] = dp[i-1][j]
            } else dp[i][j] = dp[i-1][j]
        }
    }
    return res
}
console.log(solve(n,m,v,w,s))

发表于 2022-03-12 00:19:47 回复(4)

问题信息

难度:
3条回答 100737浏览

热门推荐

通过挑战的用户

查看代码